#include <cstdint>
#include <functional>
#include <vector>
#include <memory>
#include <unordered_map>
using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;
//类被析构时自动执行任务
class TimerTask
{
private:
    uint64_t _id;          //任务的唯一编号
    uint32_t _timeout;     //任务超时时间
    bool _canceled;         //任务是否被取消
    TaskFunc _task_cb;     //任务函数    
    ReleaseFunc _release;  //用于删除时间轮中_task_map的weak_ptr

public:
    TimerTask(uint64_t id, uint32_t timeout, TaskFunc task_cb, ReleaseFunc release)
        : _id(id)
        , _timeout(timeout)
        , _canceled(false)
        , _task_cb(task_cb) 
        , _release(release)
    {}


    ~TimerTask()
    {
        if (!_canceled && _task_cb) 
        {
            //如果任务没有被取消且任务函数存在，则执行任务
            _task_cb();
        }
        if (_release) 
        {
            _release();  //执行释放函数
        }
    }

    //取消任务
    void Cancel()
    {
        _canceled = true; //标记任务为已取消
    }


    uint32_t DelayTime()const
    {
        return _timeout;
    }
};


class TimeWheel
{
private:
    using TaskPtr = std::shared_ptr<TimerTask>;
    //为了不影响shared_ptr的引用计数，使用weak_ptr来存储任务
    using WeakTaskPtr = std::weak_ptr<TimerTask>;
    std::unordered_map<uint64_t, WeakTaskPtr> _task_map; //任务映射表
    std::vector<std::vector<TaskPtr>> _wheel;  //时间轮的槽
    int _tick;
    int _capacity; //最大延迟时间
private:
    void RemoveTask(uint64_t task_id)
    {
        auto it = _task_map.find(task_id);
        if(it != _task_map.end())
        {
            _task_map.erase(it); //从映射表中删除任务
        }
    }
public:
    TimeWheel(int capacity = 60)
        : _tick(0)
        , _capacity(capacity)
    {
        _wheel.resize(capacity);  //初始化时间轮的槽
    }


    //添加任务到时间轮
    void AddTask(int task_id, uint32_t timeout, TaskFunc task_cb)
    {
        if(timeout > _capacity)
        {
            return; //超出时间轮容量，忽略任务
        }
        std::function<void()> release = std::bind(&TimeWheel::RemoveTask, this, task_id);
        TaskPtr task_ptr = std::make_shared<TimerTask>(task_id, timeout, task_cb, release);
        int pos = (_tick + timeout) % _capacity; //计算任务在时间轮中的位置
        _wheel[pos].emplace_back(task_ptr); //将任务添加到对应槽中
        _task_map[task_id] = WeakTaskPtr(task_ptr); //记录任务映射
    }


    //执行时间轮中的任务，每秒钟被调用一次
    void RunTimerTask()
    {
        _tick = (_tick + 1) % _capacity; //移动到下一个槽
        _wheel[_tick].clear(); //清空当前槽,触发shared_ptr的析构
    }


    //刷新/延迟定时任务
    void TimerRefresh(uint64_t task_id)
    {
        auto it = _task_map.find(task_id);
        if(it == _task_map.end())
        {
            return; //任务不存在
        }
        WeakTaskPtr weak_task = it->second;
        TaskPtr task_ptr = weak_task.lock(); //获取shared_ptr
        if(task_ptr == nullptr)
        {
            _task_map.erase(it); //任务已被释放，移除映射
            return;
        }
        int pos = (_tick + task_ptr->DelayTime()) % _capacity; //计算新的位置
        _wheel[pos].emplace_back(task_ptr); //重新添加到新的槽中
    }


    void TimerCancel(uint64_t task_id)
    {
        auto it = _task_map.find(task_id);
        if(it == _task_map.end())
        {
            return;   
        }
        WeakTaskPtr weak_task = it->second;
        TaskPtr task_ptr = weak_task.lock(); //获取shared_ptr
        if(task_ptr == nullptr)
        {
            _task_map.erase(it); //任务已被释放，移除映射
            return;
        }
        task_ptr->Cancel(); //取消任务
    }
};